package com.example.myapplicationktkt2.ui

import android.Manifest
import android.app.Activity
import android.content.ContentValues
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.webkit.*
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import com.example.myapplicationktkt2.R
import com.example.myapplicationktkt2.databinding.ActivityBottomNavigationBinding
import java.io.File

/**
 * WebViewActivity是一个可以显示网页内容并支持文件上传的Activity，
 * 包括从相机拍摄照片并上传的功能。
 *
 * 该Activity处理：
 * 1. WebView的设置和配置
 * 2. 相机和文件上传功能
 * 3. 相机和存储权限处理
 * 4. WebView中的返回键导航
 *
 * @author lingma
 * @since 1.0
 */
class WebViewActivity : AppCompatActivity() {
    private lateinit var webView: WebView
    private var filePathCallback: ValueCallback<Array<Uri>>? = null
    private var imageUri: Uri? = null
    private val REQUEST_SELECT_FILE = 100
    private val REQUEST_CAMERA_PERMISSION = 101

    /**
     * Activity启动时调用此方法。主要进行以下初始化工作：
     * 1. 加载UI布局
     * 2. 设置WebView
     * 3. 配置返回键行为
     *
     * @param savedInstanceState 如果Activity之前被销毁并重新创建，
     *                           此Bundle包含之前保存的状态信息
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_webview_demo)

        webView = findViewById(R.id.webview)

        // 配置WebView设置
        val webSettings = webView.settings
        webSettings.javaScriptEnabled = true
        webSettings.domStorageEnabled = true
        webSettings.allowFileAccess = true
        webSettings.allowContentAccess = true
        webSettings.databaseEnabled = true
        webSettings.useWideViewPort = true
        webSettings.loadWithOverviewMode = true

        webView.webViewClient = WebViewClient()
        webView.webChromeClient = MyWebChromeClient()

        // 加载网站
//        webView.loadUrl("http://192.168.91.103:9000/")
        webView.loadUrl("http://192.168.22.207:9999/#/login?stack-key=455b7d19")

        // 处理返回键事件
        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (webView.canGoBack()) {
                    webView.goBack()
                } else {
                    finish()
                }
            }
        })
    }

    /**
     * 自定义WebChromeClient用于处理WebView中的文件上传。
     * 允许用户从图库选择图片或使用相机拍摄新照片。
     *
     * @author lingma
     * @since 1.0
     */
    inner class MyWebChromeClient : WebChromeClient() {
        /**
         * 当WebView需要显示文件选择器以上传文件时调用此方法。
         * 该方法创建一个意图选择器，允许用户从图库选择图片或使用相机拍摄新照片。
         *
         * 处理文件选择：
         * 1. 检查是否有相机应用
         * 2. 创建意图选择器
         * 3. 添加相机意图（如果有相机且有权限）
         * 4. 启动意图选择器
         *
         * @param webView 发起文件选择器的WebView
         * @param filePathCallback 用于接收所选文件的回调
         * @param fileChooserParams 指定文件选择器行为的参数
         * @return 如果文件选择器成功显示则返回true，否则返回false
         */
        override fun onShowFileChooser(
            webView: WebView?,
            filePathCallback: ValueCallback<Array<Uri>>?,
            fileChooserParams: FileChooserParams?
        ): Boolean {
            this@WebViewActivity.filePathCallback = filePathCallback

            // 检查是否有相机应用
            val hasCameraFeature = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)

            // 创建意图选择器
            val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
            contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
            contentSelectionIntent.type = "image/*"

            val intentList = mutableListOf<Intent>()

            // 只有在有相机且有权限时才添加相机意图
            if (hasCameraFeature && checkCameraPermission()) {
                createCameraIntent()?.let { cameraIntent ->
                    intentList.add(cameraIntent)
                }
            }

            val chooserIntent = Intent(Intent.ACTION_CHOOSER)
            chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
            chooserIntent.putExtra(Intent.EXTRA_TITLE, "选择图片来源")

            if (intentList.isNotEmpty()) {
                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toTypedArray())
            }

            startActivityForResult(chooserIntent, REQUEST_SELECT_FILE)
            return true
        }
    }

    /**
     * 检查应用是否已被授予相机权限。
     *
     * @return 如果已授予相机权限则返回true，否则返回false
     */
    private fun checkCameraPermission(): Boolean {
        return ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.CAMERA
        ) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 向用户请求相机和存储权限。
     */
    private fun requestCameraPermission() {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE),
            REQUEST_CAMERA_PERMISSION
        )
    }

    /**
     * 创建一个启动相机应用拍摄照片的意图。
     * 此方法还会检查是否有相机应用可以处理该意图。
     *
     * @return 配置好的拍照意图，如果没有相机应用则返回null
     */
    private fun createCameraIntent(): Intent? {
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

        // 检查是否有应用可以处理这个意图
        if (intent.resolveActivity(packageManager) == null) {
            return null
        }

        imageUri = createImageUri()
        imageUri?.let {
            intent.putExtra(MediaStore.EXTRA_OUTPUT, it)
        }

        return intent
    }

    /**
     * 根据Android版本创建用于存储拍摄照片的URI。
     * 对于Android 10+ (Q)版本，使用MediaStore通过分区存储保存。
     * 对于较低版本，创建外部存储中的文件。
     *
     * @return 指向照片应保存位置的URI，如果创建失败则返回null
     */
    private fun createImageUri(): Uri? {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val contentValues = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, "camera_image_" + System.currentTimeMillis())
                put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
                put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
            }
            contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
        } else {
            val directory = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WebViewImages")
            if (!directory.exists()) {
                directory.mkdirs()
            }
            val file = File(directory, "camera_image_" + System.currentTimeMillis() + ".jpg")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                FileProvider.getUriForFile(
                    this,
                    "$packageName.fileprovider",
                    file
                )
            } else {
                Uri.fromFile(file)
            }
        }
    }

    /**
     * 当由此Activity启动的另一个Activity退出时调用此方法，
     * 提供启动时的requestCode、返回的resultCode以及任何附加数据。
     * 此方法处理文件选择器意图的结果，将所选文件传递回WebView。
     *
     * @param requestCode 最初提供给startActivityForResult()的整数请求代码
     * @param resultCode 子Activity返回的整数结果代码
     * @param data 可以将结果数据返回给调用方的Intent
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == REQUEST_SELECT_FILE) {
            if (resultCode == Activity.RESULT_OK) {
                var results: Array<Uri>? = null
                // 优先使用从相册选择的图片
                if (data?.data != null) {
                    results = arrayOf(data.data!!)
                }
                // 如果没有选择图片但拍了照片，则使用拍照的图片
                else if (imageUri != null) {
                    results = arrayOf(imageUri!!)
                }
                filePathCallback?.onReceiveValue(results)
            } else {
                filePathCallback?.onReceiveValue(null)
            }
            filePathCallback = null
            imageUri = null
        }
    }

    /**
     * 请求权限的结果回调。
     * 此方法处理相机权限请求的结果。
     *
     * @param requestCode 传递给requestPermissions()的请求代码
     * @param permissions 请求的权限
     * @param grantResults 相应权限的授予结果
     */
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限已授予", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this, "需要相机权限才能使用相机功能", Toast.LENGTH_LONG).show()
            }
        }
    }
}

